import json
import os
import re

import requests
from django.conf import settings
from rest_framework import serializers, status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

from authenticate import generate_jwt_token
from renameImg import imgpath
from .models import User
from django_redis import get_redis_connection


class UserRegisterModelSerializer(serializers.ModelSerializer):
    sms_code = serializers.CharField(max_length=6, min_length=4, write_only=True)
    re_password = serializers.CharField(max_length=256, min_length=3, write_only=True)
    token = serializers.CharField(max_length=256, read_only=True)

    class Meta:
        model = User
        fields = ['mobile', 'sms_code', 'password', 're_password', 'token']
        extra_kwargs = {
            'password': {'write_only': True, 'required': True, 'min_length': 3, 'max_length': 256},
            'mobile': {'write_only': True, 'required': True, 'min_length': 11, 'max_length': 11},
        }

    def validate(self, attrs):
        if attrs['password'] != attrs['re_password']:
            raise serializers.ValidationError('两次密码不一致', code='password')

        if not re.match('^1[3-9]\d{9}$', attrs['mobile']):
            raise serializers.ValidationError('手机号码格式错误', code='mobile')

        # 验证手机号码是否已注册
        if User.objects.filter(mobile=attrs['mobile']).exists() or User.objects.filter(
                username=attrs['mobile']).exists():
            raise serializers.ValidationError('手机号码已注册', code='mobile')

        # 验证短信验证码
        redis = get_redis_connection('sms_code')
        sms_code = redis.get(f'sms_{attrs["mobile"]}')
        if not sms_code:
            raise serializers.ValidationError('短信验证码已过期', code='sms_code')
            # return Response({'message': '短信验证码已过期'}, status=status.HTTP_400_BAD_REQUEST)

        if str(attrs['sms_code']) != str(sms_code.decode()):
            raise serializers.ValidationError('短信验证码错误', code='sms_code')

        return attrs

    def create(self, validated_data):
        mobile = validated_data.pop('mobile')
        password = validated_data.pop('password')
        user = User.objects.create_user(mobile=mobile, password=password, username=mobile)
        user.token = generate_jwt_token(user).get('token')
        return user


class ForgetPasswordModelSerializer(serializers.ModelSerializer):
    sms_code = serializers.CharField(max_length=6, min_length=4, write_only=True)
    re_password = serializers.CharField(max_length=256, min_length=3, write_only=True)
    token = serializers.CharField(max_length=256, read_only=True)

    class Meta:
        model = User
        fields = ['mobile', 'sms_code', 'password', 're_password', 'token']
        extra_kwargs = {
            'password': {'write_only': True, 'required': True, 'min_length': 3, 'max_length': 256},
            'mobile': {'write_only': True, 'required': True, 'min_length': 11, 'max_length': 11},
        }

    def validate(self, attrs):
        if attrs['password'] != attrs['re_password']:
            raise serializers.ValidationError('两次密码不一致', code='password')

        if not re.match('^1[3-9]\d{9}$', attrs['mobile']):
            raise serializers.ValidationError('手机号码格式错误', code='mobile')

        # 验证手机号码是否已注册
        if not User.objects.filter(mobile=attrs['mobile']).exists() and not User.objects.filter(
                username=attrs['mobile']).exists():
            raise serializers.ValidationError('手机号码未注册', code='mobile')

        # 验证短信验证码
        redis = get_redis_connection('sms_code')
        sms_code = redis.get(f'sms_{attrs["mobile"]}')
        if not sms_code:
            raise serializers.ValidationError('短信验证码已过期', code='sms_code')
            # return Response({'message': '短信验证码已过期'}, status=status.HTTP_400_BAD_REQUEST)

        if str(attrs['sms_code']) != str(sms_code.decode()):
            raise serializers.ValidationError('短信验证码错误', code='sms_code')

        return attrs

    def update(self, instance, validated_data):
        instance.set_password(validated_data['password'])
        instance.save()
        instance.token = generate_jwt_token(instance).get('token')
        return instance


import urllib.request


class UserDataModelSerializer(serializers.ModelSerializer):
    # end_fix = serializers.CharField(write_only=True, max_length=512)
    avatar = serializers.CharField(max_length=512, write_only=True)

    class Meta:
        model = User
        fields = ['avatar', 'gender', 'signature', 'is_show', 'nickname', 'age']

    def update(self, instance, validated_data):
        try:
            # 先删除原来的头像
            os.remove(os.path.join(str(settings.MEDIA_ROOT) + '/avatar/2024', str(instance.avatar)))
        except FileNotFoundError:
            pass
        instance.nickname = validated_data.get('nickname', instance.nickname)
        instance.age = validated_data.get('age', instance.age)
        instance.avatar = 'avatar/2024/' + validated_data.get('avatar') if validated_data.get(
            'avatar') else instance.avatar
        instance.gender = validated_data.get('gender', instance.gender)
        instance.signature = validated_data.get('signature', instance.signature)
        instance.is_show = validated_data.get('is_show', instance.is_show)
        instance.save()
        return instance


class UserDetailModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'avatar', 'gender', 'signature', 'is_show', 'nickname']
        extra_kwargs = {
            'avatar': {'read_only': True},
            'gender': {'read_only': True},
            'signature': {'read_only': True},
            'is_show': {'read_only': True},
            'nickname': {'read_only': True},
        }


class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)

        # 添加自定义声明
        token['user_id'] = user.id
        token['nickname'] = user.nickname
        token['signature'] = user.signature
        token['avatar'] = 'uploads/' + user.avatar.name
        token['gender'] = user.gender

        return token


